<template>
  <div v-if="inEdit" class="property-float-input-div-v2">
    <el-row>
      <el-col :span="20">
        <!-- https://blog.csdn.net/Piqzem/article/details/88908096 -->
        <!-- 限制element-ui表单中input框只能输入数字和小数点 -->
        <el-input-number
          ref="input"
          v-model="data"
          :min="min"
          :max="max"
          :step="step"
          :precision="dataPrecision"
          :controls="false"
          controls-position="right"
          size="mini"
          placeholder
          @change="onChange"
          @keyup.enter.native="onEnter"
          @blur="onBlur"
        />
      </el-col>
      <el-col :span="4">
        <el-row :gutter="2">
          <el-col :span="12">
            <!-- 下拉菜单 -->
            <el-dropdown placement="bottom" size="mini" @command="onSelect">
              <!-- 图标按钮 -->
              <el-tooltip effect="dark" content="设置精度" placement="top-start">
                <el-button icon="el-icon-setting" />
              </el-tooltip>
              <!-- 下拉菜单,通过options数据循环生成 -->
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item v-for="item in options" :key="item.value" :command="item.value">
                  <!-- 利用图标切换实现勾选效果 -->
                  <i
                    :class="dataPrecision === item.value ? 'fa fa-check-square-o' : 'fa fa-square-o'"
                  />
                  {{ item.label }}
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </el-col>
          <el-col :span="12">
            <!-- 鼠标交互按钮 -->
            <!-- <el-tooltip effect="dark" content="请在绘图窗口中选择两点" placement="top-start"> -->
            <el-button icon="el-icon-aim" @click.native="onClick" />
            <!-- </el-tooltip> -->
          </el-col>
        </el-row>
      </el-col>
    </el-row>
  </div>
  <div v-else class="no-edit-text">{{ value ? data : '*多种*' }}</div>
</template>

<script>
/*
 * 在float.vue组件的基础上增加了精度选择按钮
 * 用户可根据实际需要,灵活调节显示精度
 * 说明: 1) 精度的选择不会影响实际的数据realData,只会影响显示结果data
 *      2) 在控件中修改数据,其小数位数会被当前所选的精度限制!!!
 *      3) 如果需要更高的精度,应先选择精度,然后再进行输入和修改
 */
import props from '../mixins/props'
// import interact from '@/mixins/interact'

export default {
  name: 'PropertyFloatV2',
  mixins: [props, interact],
  props: {
    // 最大精度
    precision: {
      type: Number,
      required: false,
      default: 6 // 默认小数点后1位
    },
    // 最小值
    min: {
      type: Number,
      required: false,
      default: -Infinity
    },
    // 最大值
    max: {
      type: Number,
      required: false,
      default: Infinity
    }
  },
  data() {
    return {
      // 显示值
      data: 0,
      // 实际精度
      dataPrecision: 1,
      // 实际值
      realData: 0,
      // 选项列表
      options: [
        {
          value: 1,
          label: '1位'
        },
        {
          value: 2,
          label: '2位'
        },
        {
          value: 3,
          label: '3位'
        },
        {
          value: 4,
          label: '4位'
        },
        {
          value: 5,
          label: '5位'
        },
        {
          value: 6,
          label: '6位'
        }
      ]
    }
  },
  computed: {
    // 计算步长
    step: function() {
      return 1 / Math.pow(10, this.dataPrecision)
    }
  },
  watch: {
    // 用户切换精度时,自动更新显示值
    // 注: 实际值realData不变!!!
    dataPrecision(newVal) {
      // console.log('watch dataPrecision:', this.realData, newVal)
      this.data = this.formatValue(this.realData, newVal)
    }
  },
  created() {
    // 自动判断实际的小数点位数
    this.dataPrecision = this.getPrecision(this.value)
    if (this.dataPrecision > this.precision) {
      this.dataPrecision = this.precision
    }
    // 更新显示值
    const f = this.toFloat(this.value)
    this.data = this.formatValue(f, this.dataPrecision)
    this.realData = this.formatValue(f, this.precision)
  },
  methods: {
    // 辅助函数: 格式化数据
    formatValue(data, dataPrecision) {
      // https://www.cnblogs.com/Jacklovely/p/6554278.html
      const base = Math.pow(10, dataPrecision)
      return Math.round(data * base) / base
    },
    // 辅助函数: 自动判断小数点位数(字符串浮点数)
    getPrecision(value) {
      // console.log('getPrecision:', value)
      const s = value.split('.')
      if (s === undefined || s === null || s.length !== 2) {
        return 2
      } else if (s[1].length > 6) {
        return 6
      } else {
        return s[1].length
      }
    },
    // 用户切换数据显示精度
    // 注: 显示精度的变化不影响实际值realData
    onSelect(command) {
      this.dataPrecision = command
    },
    // 参见: interact.js/onUpdateCmdResult()函数
    onUpdateCmdResult(result) {
      // console.log('浮点数 -> onUpdateCmdResult:', result, typeof result)
      this.dataPrecision = this.getPrecision(result.toString())
      if (this.dataPrecision > this.precision) {
        this.dataPrecision = this.precision
      }
      this.data = this.formatValue(result, this.dataPrecision)
      this.realData = this.formatValue(result, this.precision)
      // 向父组件发送change消息(参数需转换为json字符串!!!)
      this.$emit('change', JSON.stringify(this.realData))
    },
    onClick() {
      // 参见: interact.js/getDistance()函数
      // this.getDistance()
    },
    onChange(val) {
      // console.log('float onChange:', val, this.realData)
      // 更新实际值和实际精度
      this.realData = val
      // 向父组件发送change消息(参数需转换为json字符串!!!)
      this.$emit('change', JSON.stringify(this.realData))
    },
    onEnter(event) {
      const val = parseFloat(event.target.value)
      this.data = val
      this.realData = val
      // 向父组件发送change消息(参数需转换为json字符串!!!)
      this.$emit('change', JSON.stringify(this.realData))
    },
    onBlur(event) {
      // console.log('float-v2.vue 失去焦点')
      if (this.inEdit) {
        // 强行夺回焦点
        this.$refs.input.focus()
      }
    }
  }
}
</script>

<style lang="scss">
%input-number-size {
  width: 18px !important;
  height: 18px !important;
  line-height: 18px !important;
  font-size: 12px !important;
}

.property-float-input-div-v2 {
  .el-input-number {
    width: 100% !important;
    .el-input__inner {
      text-align: left !important;
    }
  }
}
</style>
